<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        .box{width:100px;height:100px;background: red;position: absolute;left:0;top:0;}
    </style>
</head>
<body>
    <div class="box">hello world</div>
</body>
<script>

    // 1. 选择器
    var oBox = document.querySelector(".box");
    var clientW = document.documentElement.clientWidth;
    var clientH = document.documentElement.clientHeight;
    var oBoxW = oBox.offsetWidth;
    var oBoxH = oBox.offsetHeight;

    // 2. oBox身上按下鼠标事件
    oBox.onmousedown = function(eve){
        // 5. 获取按下时的事件对象，用于将来获取按下时的坐标
        var downE = eve || window.event;

        // 12. 阻止按下的默认事件，防止用户选中拖拽容器内的文字
        downE.preventDefault();

        // 3. 按下之后，添加移动事件
        document.onmousemove = function(eve){
            // 4. 获取移动时的事件对象，用于获取移动过程中的坐标
            var moveE = eve || window.event;
            // 6. 鼠标相对于页面的坐标 - 按下时相对于元素的坐标，
            var l = moveE.pageX - downE.offsetX;
            var t = moveE.pageY - downE.offsetY;
            // 10. 边界限定
            if(l < 0) l = 0;
            if(t < 0) t = 0;
            if( l > clientW-oBoxW ) l = clientW-oBoxW;
            if( t > clientH-oBoxH ) t = clientH-oBoxH;
            // 7. 将处理之后的left和top设置给元素
            oBox.style.left = l + "px"
            oBox.style.top = t + "px"
        }
        // 8. 按下之后，添加抬起事件
        document.onmouseup = function(){
            // 9. 抬起后，不应再有移动，删除移动事件
            document.onmousemove = null;
            // 11. 节省性能，抬起只有，可以清除自身，因为下次按下会重新绑定抬起事件
            document.onmouseup = null;
        }
    }

    
</script>
</html>